#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <fstream>
#include <regex>
#include <unordered_map>
#include <ctime>
#include <fstream>
#include <mutex>
#include <sstream>
#include <cstdarg>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include "Buffer.hpp"
#include "Log.hpp"
#include "TcpServer.hpp"
namespace HttpLib
{
#define SPACE ' '
#define SPACE_STR " "
    // HTTP工具类
    class Util
    {
    private:
        // 判断是是字母或者数字字符
        static bool IsletterOrNumChar(char x)
        {
            if ((x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9'))
            {
                return true;
            }
            return false;
        }
        // 十六进制转十进制
        static char HexToi(char ch)
        {
            if (ch >= '0' && ch <= '9')
            {
                return ch - '0';
            }
            else if (ch == 'a' && ch <= 'z')
            {
                return ch - 'a' + 10;
            }
            else if (ch >= 'A' && ch <= 'Z')
            {
                return ch - 'A' + 10;
            }
            else
            {
                LOG(ERROR, "字符%c转十六进制失败!\n", ch);
            }
            return -1;
        }

    public:
        // 字符串分割
        static size_t Spilit(const std::string &str, const std::string &sep, std::vector<std::string> *array)
        {
            size_t pos = 0, beg = 0, size = str.size();
            while (beg < size)
            {
                pos = str.find(sep, beg);
                if (pos == std::string::npos)
                {
                    if (beg < size)
                    {
                        array->push_back(str.substr(beg, size - beg + 1));
                    }
                    break;
                }
                std::string sub = str.substr(beg, pos - beg);
                if (!sub.empty())
                {
                    array->push_back(sub);
                }
                beg = pos + 1;
            }
            return array->size();
        }
        // 读取文件内容
        static bool ReadFile(const std::string &filename, std::string *buff)
        {
            std::ifstream ifs(filename, std::ios::binary);
            if (!ifs.is_open())
            {
                LOG(ERROR, "读取文件%s失败!\n", filename.c_str());
                ifs.close();
                return false;
            }
            ifs.seekg(0, ifs.end);
            int length = ifs.tellg();
            ifs.seekg(0, ifs.beg);
            buff->resize(length + 1);
            ifs.read(&(*buff)[0], length);
            if (ifs.good() == false)
            {
                LOG(ERROR, "读取文件%s失败!\n", filename.c_str());
                ifs.close();
                return false;
            }
            ifs.close();
            return true;
        }
        // 向文件写入数据
        static bool WriteFile(const std::string &filename, const std::string &buff)
        {
            std::ofstream ofs(filename, std::ios::binary | std::ios::app);
            if (!ofs.is_open())
            {
                LOG(ERROR, "写入文件%s失败!\n", filename.c_str());
                ofs.close();
                return false;
            }
            ofs.write(buff.c_str(), buff.size());
            if (ofs.good() == false)
            {
                LOG(ERROR, "写入文件%s失败!\n", filename.c_str());
                ofs.close();
                return false;
            }
            ofs.close();
            return true;
        }

        // 编码URL--convert_space_to_plus是否开启空格转+号
        static std::string EncodeUrl(const std::string &request, bool convert_space_to_plus)
        {
            std::string resp;
            for (auto &ch : request)
            {
                if (ch == '.' || ch == '-' || ch == '_' || ch == '~' || IsletterOrNumChar(ch))
                {
                    // 不用转换的字符
                    resp += ch;
                    continue;
                }
                if (ch == SPACE && convert_space_to_plus)
                {
                    resp += '+';
                    continue;
                }
                std::string temp;
                temp.resize(4);
                sprintf(&temp[0], "%%%02X", ch);
                resp += temp;
            }
            return resp;
        }
        // 解码URL---十六进制转换回去
        static std::string DecodeUrl(const std::string &request, bool convert_space_to_plus)
        {
            std::string resp;
            for (int i = 0; i < request.size(); i++)
            {
                if (request[i] == '+' && convert_space_to_plus)
                {
                    resp += " ";
                }
                else if (request[i] == '%' && (i + 2 < request.size()))
                {
                    char v1 = HexToi(request[i + 1]);
                    char v2 = HexToi(request[i + 2]);
                    char res = v1 * 16 + v2;
                    resp += res;
                    i += 2;
                }
                else
                {
                    resp += request[i];
                }
            }
            return resp;
        }

        // 获取HTTP状态码/描述信息
        static std::string GetStatusDesc(int statu)
        {
            static std::unordered_map<int, std::string> status = {{100, "Continue"},
                                                                  {101, "Switching Protocol"},
                                                                  {102, "Processing"},
                                                                  {103, "Early Hints"},
                                                                  {200, "OK"},
                                                                  {201, "Created"},
                                                                  {202, "Accepted"},
                                                                  {203, "Non-Authoritative Information"},
                                                                  {204, "No Content"},
                                                                  {205, "Reset Content"},
                                                                  {206, "Partial Content"},
                                                                  {207, "Multi-Status"},
                                                                  {208, "Already Reported"},
                                                                  {226, "IM Used"},
                                                                  {300, "Multiple Choice"},
                                                                  {301, "Moved Permanently"},
                                                                  {302, "Found"},
                                                                  {303, "See Other"},
                                                                  {304, "Not Modified"},
                                                                  {305, "Use Proxy"},
                                                                  {306, "unused"},
                                                                  {307, "Temporary Redirect"},
                                                                  {308, "Permanent Redirect"},
                                                                  {400, "Bad Request"},
                                                                  {401, "Unauthorized"},
                                                                  {402, "Payment Required"},
                                                                  {403, "Forbidden"},
                                                                  {404, "Not Found"},
                                                                  {405, "Method Not Allowed"},
                                                                  {406, "Not Acceptable"},
                                                                  {407, "Proxy Authentication Required"},
                                                                  {408, "Request Timeout"},
                                                                  {409, "Conflict"},
                                                                  {410, "Gone"},
                                                                  {411, "Length Required"},
                                                                  {412, "Precondition Failed"},
                                                                  {413, "Payload Too Large"},
                                                                  {414, "URI Too Long"},
                                                                  {415, "Unsupported Media Type"},
                                                                  {416, "Range Not Satisfiable"},
                                                                  {417, "Expectation Failed"},
                                                                  {418, "I'm a teapot"},
                                                                  {421, "Misdirected Request"},
                                                                  {422, "Unprocessable Entity"},
                                                                  {423, "Locked"},
                                                                  {424, "Failed Dependency"},
                                                                  {425, "Too Early"},
                                                                  {426, "Upgrade Required"},
                                                                  {428, "Precondition Required"},
                                                                  {429, "Too Many Requests"},
                                                                  {431, "Request Header Fields Too Large"},
                                                                  {451, "Unavailable For Legal Reasons"},
                                                                  {501, "Not Implemented"},
                                                                  {502, "Bad Gateway"},
                                                                  {503, "Service Unavailable"},
                                                                  {504, "Gateway Timeout"},
                                                                  {505, "HTTP Version Not Supported"},
                                                                  {506, "Variant Also Negotiates"},
                                                                  {507, "Insufficient Storage"},
                                                                  {508, "Loop Detected"},
                                                                  {510, "Not Extended"},
                                                                  {511, "Network Authentication Required"}};
            auto pos = status.find(statu);
            return pos == status.end() ? "unknow" : pos->second;
        }
        // 根据文件后缀名获取Content-Type
        static std::string GetMimeExt(const std::string &filename)
        {
            static std::unordered_map<std::string, std::string> mime = {{".aac", "audio/aac"},
                                                                        {".abw", "application/x-abiword"},
                                                                        {".arc", "application/x-freearc"},
                                                                        {".avi", "video/x-msvideo"},
                                                                        {".azw", "application/vnd.amazon.ebook"},
                                                                        {".bin", "application/octet-stream"},
                                                                        {".bmp", "image/bmp"},
                                                                        {".bz", "application/x-bzip"},
                                                                        {".bz2", "application/x-bzip2"},
                                                                        {".csh", "application/x-csh"},
                                                                        {".css", "text/css"},
                                                                        {".csv", "text/csv"},
                                                                        {".doc", "application/msword"},
                                                                        {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
                                                                        {".eot", "application/vnd.ms-fontobject"},
                                                                        {".epub", "application/epub+zip"},
                                                                        {".gif", "image/gif"},
                                                                        {".htm", "text/html"},
                                                                        {".html", "text/html"},
                                                                        {".ico", "image/vnd.microsoft.icon"},
                                                                        {".ics", "text/calendar"},
                                                                        {".jar", "application/java-archive"},
                                                                        {".jpeg", "image/jpeg"},
                                                                        {".jpg", "image/jpeg"},
                                                                        {".js", "text/javascript"},
                                                                        {".json", "application/json"},
                                                                        {".jsonld", "application/ld+json"},
                                                                        {".mid", "audio/midi"},
                                                                        {".midi", "audio/x-midi"},
                                                                        {".mjs", "text/javascript"},
                                                                        {".mp3", "audio/mpeg"},
                                                                        {".mpeg", "video/mpeg"},
                                                                        {".mpkg", "application/vnd.apple.installer+xml"},
                                                                        {".odp", "application/vnd.oasis.opendocument.presentation"},
                                                                        {".ods", "application/vnd.oasis.opendocument.spreadsheet"},
                                                                        {".odt", "application/vnd.oasis.opendocument.text"},
                                                                        {".oga", "audio/ogg"},
                                                                        {".ogv", "video/ogg"},
                                                                        {".ogx", "application/ogg"},
                                                                        {".otf", "font/otf"},
                                                                        {".png", "image/png"},
                                                                        {".pdf", "application/pdf"},
                                                                        {".ppt", "application/vnd.ms-powerpoint"},
                                                                        {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
                                                                        {".rar", "application/x-rar-compressed"},
                                                                        {".rtf", "application/rtf"},
                                                                        {".sh", "application/x-sh"},
                                                                        {".svg", "image/svg+xml"},
                                                                        {".swf", "application/x-shockwave-flash"},
                                                                        {".tar", "application/x-tar"},
                                                                        {".tif", "image/tiff"},
                                                                        {".tiff", "image/tiff"},
                                                                        {".ttf", "font/ttf"},
                                                                        {".txt", "text/plain"},
                                                                        {".vsd", "application/vnd.visio"},
                                                                        {".wav", "audio/wav"},
                                                                        {".weba", "audio/webm"},
                                                                        {".webm", "video/webm"},
                                                                        {".webp", "image/webp"},
                                                                        {".woff", "font/woff"},
                                                                        {".woff2", "font/woff2"},
                                                                        {".xhtml", "application/xhtml+xml"},
                                                                        {".xls", "application/vnd.ms-excel"},
                                                                        {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
                                                                        {".xml", "application/xml"},
                                                                        {".xul", "application/vnd.mozilla.xul+xml"},
                                                                        {".zip", "application/zip"},
                                                                        {".3gp", "video/3gpp"},
                                                                        {".3g2", "video/3gpp2"},
                                                                        {".7z", "application/x-7z-compressed"}};
            // 从后往前找
            auto pos = filename.find_last_of(".");
            if (pos == std::string::npos)
            {
                // 没有后缀，返回application/octet-stream--表示二进制信息
                return "application/octet-stream";
            }
            auto res = mime.find(filename.substr(pos));
            return res->second;
        }
        // 判断一个文件是否是目录
        static bool IsDir(const std::string &filename)
        {
            struct stat st;
            int n = ::stat(filename.c_str(), &st);
            if (n < 0)
            {
                LOG(DEBUG, "LOG(ERROR,%s文件不存在!\n", filename.c_str());
                return false;
            }
            return S_ISDIR(st.st_mode);
        }
        // 判断一个文件是否是普通文件
        static bool IsNormalFile(const std::string &filename)
        {
            struct stat st;
            int n = ::stat(filename.c_str(), &st);
            if (n < 0)
            {
                // LOG(ERROR, "LOG(ERROR,%s文件不存在!\n", filename.c_str());
                return false;
            }
            return S_ISREG(st.st_mode);
        }
        // HTTP资源路径的有效性判断
        static bool IsValidUrl(const std::string &url)
        {
            int count = 0;
            std::vector<std::string> arrays;
            Spilit(url, "/", &arrays);
            for (auto &str : arrays)
            {
                if (str == "..")
                {
                    count--;
                    if (count < 0)
                    {
                         return false;
                    }
                }
                else
                {
                    ++count;
                }
            }
            LOG(DEBUG,"path: %s 合法!\n",url.c_str());
            return true;
        }
    };

    // HTTP请求Request
    struct Request
    {
        // 请求方法
        std::string _method;
        // 资源路径--URL
        std::string _url;
        // 协议版本
        std::string _version;
        // 请求正文
        std::string _body;
        // 正则表达式提取的资源路径的结果集
        std::smatch _matches;
        // HTTP请求头部kv值
        std::unordered_map<std::string, std::string> _headers;
        // HTTP请求查询的字符串
        std::unordered_map<std::string, std::string> _search_params;
        // 设置头部字段
        void SetHeader(const std::string &key, const std::string &value)
        {
            _headers.insert(std::make_pair(key, value));
        }
        // 是否存在某个头部字段
        std::pair<bool, std::unordered_map<std::string, std::string>::iterator> HasHeader(const std::string &key)
        {
            auto pos = _headers.find(key);
            if (pos == _headers.end())
                return std::make_pair(false, pos);
            return std::make_pair(true, pos);
        }
        // 返回一个头部字段的value;
        std::string GetHeader(const std::string &key)
        {
            auto iter = HasHeader(key);
            if (iter.first == true)
            {
                return (iter.second)->second;
            }
            else
            {
                // 返回空串
                return "";
            }
        }
        // 设置查询字符串集合
        void SetParams(const std::string &key, const std::string &value)
        {
            _search_params.insert(std::make_pair(key, value));
        }
        // 判断是否有某个指定的查询字符串
        std::pair<bool, std::unordered_map<std::string, std::string>::iterator> HasParam(const std::string &key)
        {
            auto pos = _search_params.find(key);
            if (pos != _search_params.end())
            {
                return std::make_pair(true, pos);
            }
            return std::make_pair(false, pos);
        }
        // 获取查询url的参数
        std::string GetParam(const std::string &key)
        {
            auto iter = HasParam(key);
            if (iter.first == true)
            {
                return (iter.second)->second;
            }
            else
            {
                // 返回空串
                return "";
            }
        }
        // 获取HTTP请求的正文长度
        size_t GetBodyLength()
        {
            std::string res = GetHeader("Connent-Length");
            if (res.empty())
                return 0;
            return std::stoi(res);
        }
        // 判断是否是长连接
        bool IsKeepConnection()
        {
            std::string res = GetHeader("Connection");
            if (res == "keep-alive" || res == "Keep-Alive")
            {
                return true;
            }
            return false;
        }
        // 重置请求字段
        void ReSet()
        {
            _method.clear();
            _url.clear();
            _version.clear();
            _body.clear();
            std::smatch temp;
            _matches.swap(temp);
            _headers.clear();
        }
    };

    // HTTP响应
    struct Respence
    {
        // HTTP响应状态码
        int _status;
        // 是否开启重定向
        bool _redirect_flag;
        // 重定向后的url
        std::string _redirect_url;
        // HTTP响应正文
        std::string _body;
        // 头部字段
        std::unordered_map<std::string, std::string> _headers;
        Respence(int status = 200) : _status(status), _redirect_flag(false)
        {
        }
        ~Respence()
        {
        }
        // 重置字段信息
        void Reset()
        {
            _status = 0;
            _redirect_flag = false;
            _redirect_url.clear();
            _body.clear();
            _headers.clear();
        }
        // 新增头部字段信息
        void SetHeader(const std::string &key, const std::string &values)
        {
            _headers.insert(std::make_pair(key, values));
        }
        // 判断某个头部字段是否存在
        std::pair<bool, std::unordered_map<std::string, std::string>::iterator> HasHeader(const std::string &key)
        {
            auto pos = _headers.find(key);
            if (pos == _headers.end())
            {
                return std::make_pair(false, pos);
            }
            return std::make_pair(true, pos);
        }
        // 获取指定头部字段的信息
        std::string GetHeader(const std::string &key)
        {
            auto iter = HasHeader(key);
            return (iter.first) == true ? (iter.second)->second : "";
        }
        // 设置body字段,并添加正文类型
        void SetConntent(const std::string &body, const std::string &type)
        {
            _body = body;
            SetHeader("Content-Type", type);
        }
        // 设置重定向url
        void SetRedirectUrl(const std::string &new_url, int status = 302)
        {
            _redirect_flag = true;
            _status = status;
            _redirect_url = new_url;
        }
        // 判断是否是长连接
        bool IsKeepConnection()
        {
            std::string res = GetHeader("Connection");
            if (res == "keep-alive" || res == "Keep-Alive")
            {
                return true;
            }
            return false;
        }
    };
#define MAX_LINE_SIZE 8192
    // HTTP--Conntext模块--状态机
    enum class Contxt_Status
    {
        RECV_HTTP_ERROR,
        RECV_HTTP_LINE,
        RECV_HTTP_HEAD,
        RECV_HTTP_BODY,
        RECV_HTTP_OVER
    };
    class HttpContext
    {
    private:
        // 响应状态码
        int _http_statu;
        // 解析状态
        Contxt_Status _recv_statu;
        // 存放解析完毕的HTTP请求
        Request _request;

    private:
        // 接收Http请求行
        bool RecvHttpLine(Buffer *buff)
        {
            _recv_statu = Contxt_Status::RECV_HTTP_LINE;
            std::string line = buff->GetLineAndPop();
            if (line.size() == 0)
            {
                // 缓冲区一行数据太长
                if (buff->ReadAbleSize() > MAX_LINE_SIZE)
                {
                    _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                    /*--url is too long*/
                    _http_statu = 414;
                    LOG(ERROR, "缓冲区中一行的数据过长!\n");
                    return false;
                }
                LOG(ERROR, "缓冲区中的数据不足一行!\n");
                return true;
            }
            // 缓冲区一行数据太长
            if (line.size() > MAX_LINE_SIZE)
            {
                _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                /*--url is too long*/
                _http_statu = 414;
                LOG(ERROR, "缓冲区中一行的数据过长!\n");
                return false;
            }
            return ParseHttpLine(line);
        }
        // 解析Http请求行
        bool ParseHttpLine(const std::string &line)
        {
            // GET WWWRoot/index.html HTTP/1.1 \r\n
            std::smatch matches;
            std::regex e("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?", std::regex::icase);
            bool ret = std::regex_match(line, matches, e);
            if (ret == false)
            {
                _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                _http_statu = 400;
                return false;
            }
            _request._method = matches[1];
            _request._url = Util::DecodeUrl(matches[2], false);
            // matches[3]中是查询字符串
            _request._version = matches[4];
            // 解析查询字符串: user=xxx&pass=xxx
            std::string query = matches[3];
            std::vector<std::string> rets;
            Util::Spilit(query, "&", &rets);
            for (auto &ret : rets)
            {
                auto pos = ret.find("=");
                if (pos == std::string::npos)
                {
                    return false;
                }
                std::string key = Util::DecodeUrl(ret.substr(0, pos), true);
                std::string val = Util::DecodeUrl(ret.substr(pos + 1), true);
                LOG(DEBUG, "[HTTP-Request]--查询字符串:key = %s --val = %\n", key.c_str(), val.c_str());
                _request.SetParams(key, val);
            }
            _recv_statu = Contxt_Status::RECV_HTTP_HEAD;
            return true;
        }
        // 接收Http头部信息
        bool RecvHttpHeader(Buffer *buff)
        {
            if (_recv_statu != Contxt_Status::RECV_HTTP_HEAD)
            {
                _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                /*--url is too long*/
                _http_statu = 400;
                LOG(ERROR, "HTTP接收状态异常!\n");
                return false;
            }
            while (true)
            {
                std::string line = buff->GetLineAndPop();
                if (line == "\r\n" || line == "\n")
                {
                    break;
                }
                if (line.size() == 0)
                {
                    // 缓冲区一行数据太长
                    if (buff->ReadAbleSize() > MAX_LINE_SIZE)
                    {
                        _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                        /*--url is too long*/
                        _http_statu = 414;
                        LOG(ERROR, "缓冲区中一行的数据过长!\n");
                        return false;
                    }
                    LOG(DEBUG, "缓冲区中的数据不足一行!\n");
                    return true;
                }
                // 缓冲区一行数据太长
                if (line.size() > MAX_LINE_SIZE)
                {
                    _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                    /*--url is too long*/
                    _http_statu = 414;
                    LOG(ERROR, "缓冲区中一行的数据过长!\n");
                    return false;
                }
                if (!ParseHttpHeader(line))
                {
                    return false;
                }
            }
            return true;
        }
        // 解析Http请求行
        bool ParseHttpHeader(std::string &line)
        {
            if(line.back() == '\n') line.pop_back();
            if(line.back() == '\r') line.pop_back();
            auto pos = line.find(": ");
            if (pos == std::string::npos)
            {
                _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                /*--url is too long*/
                _http_statu = 400;
                LOG(ERROR, "HTTP请求头部异常!\n");
                return false;
            }
            std::string key = line.substr(0, pos);
            std::string val = line.substr(pos + 2);
            LOG(DEBUG, "[HTTP-Request]--头部字段:key = %s --val = %s\n", key.c_str(), val.c_str());
            _request.SetHeader(key, val);
            _recv_statu = Contxt_Status::RECV_HTTP_BODY;
            return true;
        }
        // 接收Http正文
        bool RecvHttpBody(Buffer *buff)
        {
            if (_recv_statu != Contxt_Status::RECV_HTTP_BODY)
            {
                _recv_statu = Contxt_Status::RECV_HTTP_ERROR;
                /*--url is too long*/
                _http_statu = 400;
                LOG(ERROR, "HTTP接收状态异常!\n");
                return false;
            }
            size_t len = _request.GetBodyLength();
            size_t recved_len = _request._body.size();
            // 还需要的正文长度
            size_t remain_len = len - recved_len;
            if (buff->ReadAbleSize() >= remain_len)
            {
                _request._body += buff->ReadAsStringAndPop(remain_len);
                _recv_statu = Contxt_Status::RECV_HTTP_OVER;
                return true;
            }
            else
            {
                _request._body += buff->ReadAsStringAndPop(buff->ReadAbleSize());
            }
            return true;
        }

    public:
        HttpContext() : _http_statu(200), _recv_statu(Contxt_Status::RECV_HTTP_LINE)
        {
        }
        // 重置
        void Reset()
        {
            _http_statu = 200;
            _recv_statu = Contxt_Status::RECV_HTTP_LINE;
            _request.ReSet();
        }
        // 获取解析状态
        Contxt_Status RecvStatu()
        {
            return _recv_statu;
        }
        // 获取响应状态码
        int RespStatuCode()
        {
            return _http_statu;
        }
        Request &GetRequest()
        {
            return _request;
        }
        // 负责转发所有的HTTP解析接口
        void DispatchHandleHttpRequest(Buffer *buff)
        {
            switch (_recv_statu)
            {
            case Contxt_Status::RECV_HTTP_LINE:
                RecvHttpLine(buff);
            case Contxt_Status::RECV_HTTP_HEAD:
                RecvHttpHeader(buff);
            case Contxt_Status::RECV_HTTP_BODY:
                RecvHttpBody(buff);
            }
            return;
        }
    };
#define DEFAULT_TIMEOUT 10
    //             [请求--方法] 路由表
    /*   - -- -- -- -- ---------------
        | 请求方法    |   函数指针     |
       |  GET url    |     handler    |
       |      ...    |     ...        |
       -------------------------------*/
    // 对于映射关系：不能直接只使用stirng -- function 可以使用正则表达式！即pattern(string)-- function
    class HttpServer
    {
    private:
        using Handler_t = std::function<void(const Request &, Respence *)>;
        using RouteTable_t = std::vector<std::pair<std::regex, Handler_t>>;
        TcpServer _server;
        // 路由表
        RouteTable_t _get_route;
        RouteTable_t _post_route;
        RouteTable_t _delete_route;
        RouteTable_t _put_route;
        // 静态资源根目录
        std::string _base_dir;

    private:
        // 错误页面
        void ErrorHandler(const Request &req, Respence *rsp)
        {
            std::string error_html = R"(<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>错误：未找到处理程序</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f8f9fa;
            color: #343a40;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        .error-container {
            text-align: center;
            padding: 20px;
            border: 1px solid #e3e6f0;
            border-radius: 8px;
            background-color: #ffffff;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #dc3545;
        }
        p {
            font-size: 16px;
        }
        a {
            color: #007bff;
            text-decoration: none;
        }
        a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div class="error-container">
        <h1>404 - 未找到处理程序</h1>
        <p>服务器未找到请求资源的处理程序。</p>
        <p>可能的原因：</p>
        <ul>
            <li>请求的 URL 不正确。</li>
            <li>服务器不支持请求的 HTTP 方法。</li>
            <li>服务器未定义该资源或路由。</li>
        </ul>
    </div>
</body>
</html>)";
            rsp->SetConntent(error_html, "text/html");
        }
        // 判断是否是静态资源请求
        bool IsStaticFileRequst(const Request &req)
        {
            if (_base_dir.size() == 0)
            {
                LOG(ERROR, "静态资源根目录未设置!\n");
                return false;
            }
            if (req._method != "GET" && req._method != "HEAD")
            {
                return false;
            }
            if (!Util::IsValidUrl(req._url))
            {
                LOG(DEBUG, "本次请求的url不存在!\n");
                return false;
            }
            std::string url = _base_dir + req._url;
            if (req._url.back() == '/')
            {
                // 给一个登陆界面
                url += "index.html";
            }
            if(!Util::IsNormalFile(url))
            {
                return false;
            }
            return true;
        }
        // 处理静态资源请求
        void HandlerStaticRequest(const Request &req, Respence *rsp)
        {
            // 此时已经是有效的了
            std::string path = _base_dir + req._url;
            if (req._url.back() == '/')
            {
                // 给一个登陆界面
                path += "index.html";
            }
            if (!Util::ReadFile(path, &(rsp->_body)))
            {
                return;
            }
            // 添加后缀
            std::string mime = Util::GetMimeExt(path);
            rsp->SetHeader("Content-Type", mime);
        }
        void Dispatch(Request &req, Respence *rsp, RouteTable_t table)
        {
            // 遍历table即可
            for (auto &iter : table)
            {
                std::regex rgx = iter.first;
                const Handler_t handler = iter.second;
                if (!std::regex_match(req._url, req._matches, rgx))
                {
                    continue;
                }
                return handler(req, rsp);
            }
            rsp->_status = 404;
            return;
        }
        // 路由转发
        void Route(Request &req, Respence *rsp)
        {
            // 先判断是否是请求静态资源
            if (IsStaticFileRequst(req))
            {
                return HandlerStaticRequest(req, rsp);
            }
            // 判断method
            if (req._method == "GET" || req._method == "HEAD")
            {
                return Dispatch(req, rsp, _get_route);
            }
            else if (req._method == "POST")
            {
                return Dispatch(req, rsp, _post_route);
            }
            else if (req._method == "DELETE")
            {
                return Dispatch(req, rsp, _delete_route);
            }
            else if (req._method == "PUT")
            {
                return Dispatch(req, rsp, _put_route);
            }
            // 如果都不是，则返回404
            rsp->_status = 405;
            return;
        }

        void OnConnected(const ConnectionPtr &conn)
        {
            conn->SetContext(HttpContext());
            LOG(DEBUG, "new connection : %p\n", conn.get());
        }
        // 构建响应并发回
        void BuildRespence(const ConnectionPtr &conn, Request &req, Respence &rsp)
        {
            // 先填充头部
            // 判断是否是长连接
            if (req.IsKeepConnection())
            {
                LOG(DEBUG,"Connection是长连接!\n");
                rsp.SetHeader("Connection", "keep-alive");
            }
            else
            {
                LOG(DEBUG,"Connection是短连接!\n");
                rsp.SetHeader("Connection", "close");
            }
            // 填充正文长度信息
            rsp.SetHeader("Content-Length", std::to_string(rsp._body.size()));
            if (rsp._body.size() == 0 && rsp.HasHeader("Content-Type").first == false)
            {
                rsp.SetHeader("Content-Type", "application/octet-stream");
            }
            // 是否重定向
            if (rsp._redirect_flag == true)
            {
                rsp.SetHeader("Location", rsp._redirect_url);
            }
            std::stringstream ss;
            // 先组织请求行
            ss << req._version << " " << std::to_string(rsp._status) << " " << Util::GetStatusDesc(rsp._status) << "\r\n";
            // 2.添加头部
            for (auto &head : rsp._headers)
            {
                ss << head.first << ": " << head.second << "\r\n";
            }
            ss << "\r\n";
            ss << rsp._body;
            conn->Send(ss.str().c_str(), ss.str().size());
        }
        // 缓冲区数据解析+处理
        void OnMessage(const ConnectionPtr &conn, Buffer *buff)
        {
            while (buff->ReadAbleSize() > 0)
            {
                HttpContext *context = conn->Context()->get<HttpContext>();
                context->DispatchHandleHttpRequest(buff);
                // 获取Request和Respence
                Request& req = context->GetRequest();
                Respence rsp(context->RespStatuCode());
                if (rsp._status >= 400)
                {
                    ErrorHandler(req, &rsp);
                    // 构建Respence发回浏览器
                    BuildRespence(conn, req, rsp);
                    context->Reset();
                    // 清空缓冲区
                    buff->MoveReadOffset(buff->ReadAbleSize());
                    conn->Shutdown();
                    return; // 出错了就直接返回，不要再往后走了
                }
                if (context->RecvStatu() != Contxt_Status::RECV_HTTP_OVER)
                {
                    break;
                }
                Route(req, &rsp);
                BuildRespence(conn, req, rsp);
                context->Reset();
                if (!req.IsKeepConnection())
                {
                    // printf("短链接处理\n");
                    conn->Shutdown();  // 这里是一次
                }
            }
        }

    public:
        HttpServer(uint16_t port,int timeout = DEFAULT_TIMEOUT) : _server(port)
        {
            // _server.EnableInactiveRelease(timeout);
            _server.SetConnectedCallback(std::bind(&HttpServer::OnConnected,this,std::placeholders::_1));
            _server.SetMessageCallback(std::bind(&HttpServer::OnMessage,this,std::placeholders::_1,std::placeholders::_2));
        }
        void SetBaseDir(const std::string path)
        {
            _base_dir = path;
        }
        void Get(const std::string pattern, Handler_t handler)
        {
            return _get_route.push_back(std::make_pair(std::regex(pattern), handler));
        }
        void Post(const std::string pattern, Handler_t handler)
        {
            return _post_route.push_back(std::make_pair(std::regex(pattern), handler));
        }
        void Delete(const std::string pattern, Handler_t handler)
        {
            return _delete_route.push_back(std::make_pair(std::regex(pattern), handler));
        }
        void Put(const std::string pattern, Handler_t handler)
        {
            return _put_route.push_back(std::make_pair(std::regex(pattern), handler));
        }
        void EnableNoActiveConnectDestroy(int timeout)
        {
            _server.EnableInactiveRelease(timeout);
        }
        void SetThreadCount(int count)
        {
            _server.SetThreadCount(count);
        }
        void Listen()
        {
            _server.Start();
        }
    };

}
